import sys
import os
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, QLineEdit
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QPixmap, QFont, QColor
from GUI import *
from selenium import webdriver
from selenium.webdriver.common.by  import  By
from selenium.webdriver.common.keys  import  Keys
from selenium.webdriver.support  import  expected_conditions  as  EC
from selenium.webdriver.support.wait import  WebDriverWait
from PIL import Image
from threading import Thread



# 创建文件夹
path1 = 'C:\Fight for Reports'
path2 = 'C:\Fight for Reports\setting.txt'
path3 = 'C:\Fight for Reports\shot1.png'
path4 = 'C:\Fight for Reports\shot2.png'
path5 = 'C:\Fight for Reports\yzm1.png'
path6 = 'C:\Fight for Reports\yzm2.png'
if not os.path.exists(path1):
    os.makedirs(path1)
if not os.path.exists(path2):
    text = 'firefox:\nchrome:\n'
    f = open(path2, 'w')
    f.write(text)
    f.close()

class WebPage():
    def __init__(self):
        # url1
        self.url1 = 'http://yjsy.buct.edu.cn:8080//pyxx/login.aspx'
        # 启动浏览器
        f = open(path2)  # 打开配置文件
        lines = f.readlines()
        f.close()
        firefox = lines[0].strip('firefox:').strip('\n')
        chrome = lines[1].strip('chrome:').strip('\n')
        if firefox != '':
            path = firefox
            option = webdriver.FirefoxOptions()
            option.add_argument('---headless')
            self.browser = webdriver.Firefox(executable_path=path, options=option)
        if chrome != '':
           path = chrome
           option = webdriver.ChromeOptions()
           option.add_argument('---headless')
           self.browser = webdriver.Chrome(executable_path=path, options=option)
        self.browser.get(self.url1)
        self.browser.set_window_size(1024,768)

    def login(self, user, password, yzm1):
        # 显示等待并且定位
        wait = WebDriverWait(self.browser, 10)
        input1 = wait.until(EC.presence_of_element_located((By.ID, '_ctl0_txtusername')))  # 定位用户名输入框
        input2 = wait.until(EC.presence_of_element_located((By.ID, '_ctl0_txtpassword')))  # 定位密码输入框
        input3 = wait.until(EC.presence_of_element_located((By.ID, '_ctl0_txtyzm')))  # 定位验证码1输入框
        button = wait.until(EC.presence_of_element_located((By.ID, '_ctl0_ImageButton1')))  # 定位登陆按钮
        # 输入
        input1.clear()
        input2.clear()
        input3.clear()
        input1.send_keys(user)  # 输入用户名
        input2.send_keys(password)  # 输入密码
        input3.send_keys(yzm1)  # 输入验证码
        button.send_keys(Keys.ENTER)  # 点击登陆
        # 进入抢报告的网页
        url2 = 'http://yjsy.buct.edu.cn:8080/pyxx/txhdgl/hdlist.aspx?xh=' + user
        self.browser.get(url2)

    def get_lesson(self):
        if self.browser.current_url != self.url1:
            self.browser.refresh() # 点击网页刷新按钮与点击浏览器刷新按钮一回事，验证码都被刷新了，不如简单点用后者
            # 获取可以报名的报告
            reports = self.browser.find_elements_by_xpath("./*//img[@alt='我要报名']")
            satisfied_reports = []
            satisfied_reports_name = []
            reports_name = []
            # 遍历每个报告
            for report in reports:
                maxNum = report.find_element_by_xpath("../../../td[7]").get_attribute("innerText") #可报名人数
                nowNum = report.find_element_by_xpath("../../../td[8]").get_attribute("innerText") #已报名人数
                reports_name.append(report.find_element_by_xpath("../../../td[2]").get_attribute("innerText"))
                # 如果可以报名
                if maxNum > nowNum:
                    satisfied_reports.append(report)
                    report_name = report.find_element_by_xpath("../../../td[2]").get_attribute("innerText")
                    satisfied_reports_name.append(report_name)
        return reports_name, satisfied_reports, satisfied_reports_name

    def signup(self, report, yzm2):
        input1 = self.browser.find_element_by_xpath("./*//input[@name='txtyzm']")  # 定位验证码2输入框
        input1.send_keys(yzm2)  # 输入验证码
        report.click()   # 点击报名按钮

    def get_yzm1_pic(self):
        self.browser.get_screenshot_as_file(path3)  # 网页截屏
        yzm1 = self.browser.find_element_by_xpath("./*//input[@name='_ctl0:txtyzm']/../img")  # 定位验证码1
        location = yzm1.location  # 获取验证码x,y轴坐标
        size = yzm1.size  # 获取验证码的长宽
        rangle = (int(location['x']) , int(location['y']) , int(location['x'] + size['width']),
                  int(location['y'] + size['height']))  # 获取验证码所在网页的位置
        shot1 = Image.open(path3)  # 打开网页截图
        yzm1_shot = shot1.crop(rangle)  # 使用Image的crop函数，从截图中再次截取我们需要的验证码区域
        yzm1_shot.save(path5)
        # 删除图片
        if os.path.exists(path3):  # 如果文件存在，则删除
            os.remove(path3)

    def get_yzm2_pic(self):
        yzm2 = self.browser.find_element_by_xpath("./*//input[@name='txtyzm']/../img") # 定位验证码2
        self.browser.execute_script("arguments[0].scrollIntoView(false);", yzm2) # 往下滚动页面出现验证码后才可以截屏
        self.browser.get_screenshot_as_file(path4)  # 网页截屏
        shot2 = Image.open(path4)  # 打开网页截图
        left = int(yzm2.location['x'])
        if int(yzm2.location['y'] + yzm2.size['height'])>shot2.height:
            bottom = shot2.height
        else:
            bottom=int(yzm2.location['y'] + yzm2.size['height'])
        top = bottom - yzm2.size['height']
        right = int(yzm2.location['x'] + yzm2.size['width'])
        yzm2_shot = shot2.crop((left, top, right, bottom))
        yzm2_shot.save(path6)
        # 删除图片
        if os.path.exists(path4):  # 如果文件存在，则删除
            os.remove(path4)

    def refresh_yzm1(self):
        yzm1 = self.browser.find_element_by_xpath("./*//input[@name='_ctl0:txtyzm']/../img")
        yzm1.click()

    def refresh_yzm2(self):
        yzm2 = self.browser.find_element_by_xpath("./*//input[@name='txtyzm']/../img")
        yzm2.click()

    def stop(self):
        self.browser.quit()

class MyMainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        self.setupUi(self)
        # 密码、学号、验证码1、课程、验证码2
        self.user, self.password, self.lesson, self.yzm1, self.yzm2 = '', '', '', '', ''
        # lineedit保护密码
        self.lineEdit_user.setEchoMode(QLineEdit.Password)
        self.lineEdit_password.setEchoMode(QLineEdit.Password)
        # 标题栏只显示关闭按钮
        self.setWindowFlags(Qt.WindowCloseButtonHint)
        # 点击刷新、登陆、报名、访问、停止
        self.pushButton_refresh1.clicked.connect(self.push1)
        self.pushButton_refresh2.clicked.connect(self.push2)
        self.pushButton_login.clicked.connect(self.push3)
        self.pushButton_signup.clicked.connect(self.push4)
        self.pushButton_visit.clicked.connect(self.push5)
        self.pushButton_stop.setCheckable(True)  # 按钮可检查
        self.pushButton_stop.clicked.connect(self.push6)
        self.pushButton_stop.setText('监测')
        # 标签内容居中
        self.label_yzm1.setAlignment(Qt.AlignCenter)
        self.label_yzm2.setAlignment(Qt.AlignCenter)
        # 文本浏览器字体
        font = QFont()
        font.setFamily("Arial")
        font.setPointSize(10)
        self.textBrowser.setFont(font)
        color = QColor()
        color.setRgb(255, 132, 139)
        self.textBrowser.setTextColor(color)
        self.textBrowser.setText('未监测!')
        # 标签自适应文字大小
        self.label4.adjustSize()
        self.label7.adjustSize()
        self.label8.adjustSize()
        self.label9.adjustSize()
        # 显示
        self.show()
        # 实例化WebPage类
        try:
            self.webpage = WebPage()
            self.open_failure = False
        except:
            self.open_failure = True
            QMessageBox.information(self, '提示', '浏览器驱动路径设置有误,请关闭软件!', QMessageBox.Ok)
        # 实时显示报告名称
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.display_report)

    # *************显示可以报名的报告名称*************
    def display_report(self):
        try:
            reports_name, self.satisfied_reports, satisfied_reports_name = self.webpage.get_lesson()
            if len(reports_name) == 0:
                self.textBrowser.setText('目前还没有报告!')
            else:
                # 重构字符串
                string1 = '所有报告:\n'
                for r in reports_name:
                    string1 = string1 + r +'\n'
                string1 = string1 + '\n\n'
                string2 = '可以抢的报告:\n'
                for r in satisfied_reports_name:
                    string2 = string2 + r + '\n'
                string = string1 + string2
                self.textBrowser.setText(string)
        except:
            self.textBrowser.setText('还未登陆!')

    # *****************点击按钮******************
    # 刷新验证码1
    def push1(self):
        try:
            self.webpage.refresh_yzm1()  # 刷新验证码
            self.webpage.get_yzm1_pic()  # 保存图片
            self.label_yzm1.setPixmap(QPixmap(path5))  # 获取验证码1放在label上
        except:
            QMessageBox.information(self, '提示', '已经登陆,不可以刷新验证码!', QMessageBox.Ok)
    # 刷新验证码2
    def push2(self):
        try:
            self.stop_timer()  # 如果正在运行停止监测
            self.webpage.refresh_yzm2()  # 刷新验证码
            self.webpage.get_yzm2_pic()  # 保存图片
            self.label_yzm2.setPixmap(QPixmap(path6))  # 获取验证码2放在label上
        except:
            QMessageBox.information(self, '提示', '还未登陆,不可以刷新验证码!', QMessageBox.Ok)
    # 登陆
    def push3(self):
        try:
            self.user = self.lineEdit_user.text()
            self.password = self.lineEdit_password.text()
            self.yzm1 = self.lineEdit_yzm1.text()
            self.webpage.login(self.user, self.password, self.yzm1)
            # 登陆成功将登陆与刷新按钮 设为不可选
            self.pushButton_login.setEnabled(False)
            self.pushButton_refresh1.setEnabled(False)
            # 弹出消息框
            QMessageBox.information(self, '提示', '登录成功!', QMessageBox.Ok)
        except:
            QMessageBox.information(self, '提示', '输入错误!', QMessageBox.Ok)
    # 报名
    def push4(self):
        try:
            self.stop_timer()  # 如果正在运行停止监测
            self.lesson = self.lineEdit_lesson.text()
            self.yzm2 = self.lineEdit_yzm2.text()
            if len(self.satisfied_reports) != 0:
                # self.lesson为课程的编号
                self.webpage.signup(self.satisfied_reports[int(self.lesson)], self.yzm2)
            else:
                QMessageBox.information(self, '提示', '目前没有报告, 无法报名!', QMessageBox.Ok)
        except:
            QMessageBox.information(self, '提示', '可能原因: 输入错误, 未登录!', QMessageBox.Ok)
    # 访问
    def push5(self):
        path = self.webpage.chrome_browser
        thread = Thread(target=self.visit, args=(path,))
        thread.start()

    def visit(self, path):
        option = webdriver.ChromeOptions()
        option.add_experimental_option("excludeSwitches", ['enable-automation'])
        browser = webdriver.Chrome(executable_path=path, options=option)
        browser.get(self.webpage.url1)

    def stop_timer(self):
        if self.timer.isActive():
            self.timer.stop()
            QMessageBox.information(self, '提示', '停止监测!', QMessageBox.Ok)
            self.textBrowser.setText('未监测!')

    # 开始与暂停监视报告
    def push6(self):
        if self.pushButton_stop.isChecked():
            if not self.timer.isActive():
                self.timer.start(2000)
                QMessageBox.information(self, '提示', '开始监测!', QMessageBox.Ok)
            else:
                self.timer.stop()
                QMessageBox.information(self, '提示', '停止监测!', QMessageBox.Ok)
                self.textBrowser.setText('未监测!')
        else:
            if self.timer.isActive():
                self.timer.stop()
                QMessageBox.information(self, '提示', '停止监测!', QMessageBox.Ok)
                self.textBrowser.setText('未监测!')
            else:
                self.timer.start(2000)
                QMessageBox.information(self, '提示', '开始监测!', QMessageBox.Ok)

    # 重写关闭时间 退出时删除图片
    def closeEvent(self, event):
        if os.path.exists(path5):  # 如果文件存在，则删除
            os.remove(path5)
        if os.path.exists(path6):  # 如果文件存在，则删除
            os.remove(path6)
        if not self.open_failure:
            self.webpage.stop()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWin = MyMainWindow()
    sys.exit(app.exec_())